package org.gpf;

import java.io.FileOutputStream;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.CDATASection;
import org.w3c.dom.Comment;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


public class DOM_Test {

	/**
	 * @param args
	 * @throws Exception 
	 */
	public static void main(String[] args) throws Exception {
		
		domParser("res/books.xml");
		
		newXml("res/books_dom_out.xml");
	}

	public static void newXml(String url) throws Exception {
		
		Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
		Element books = document.createElement("books");
		
		Element book = document.createElement("book");
		
		Element name = document.createElement("name");
		Element author = document.createElement("author");
		Element price = document.createElement("price");
		Element year = document.createElement("year");
		
		name.setTextContent("面向对象程序设计");
		author.appendChild(document.createTextNode("杰克·凯文"));
		price.setTextContent("56.3");
		year.setTextContent("2012");
		
		book.setAttribute("id", "001");
		Comment comment = document.createComment("注释1");
		book.appendChild(comment);
		book.appendChild(name);
		book.appendChild(author);
		book.appendChild(price);
		book.appendChild(year);
		
		CDATASection cdata = document.createCDATASection("这是CDATA节点");
		book.insertBefore(cdata, year);
		books.appendChild(book);
		document.appendChild(books);
		
		Transformer tf = TransformerFactory.newInstance().newTransformer();
		tf.setOutputProperty(OutputKeys.ENCODING, "utf-8");
		tf.setOutputProperty(OutputKeys.INDENT, "yes");
		tf.transform(new DOMSource(document), new StreamResult(new FileOutputStream(url)));
	}

	/**
	 * 解析xml
	 */
	public static void domParser(String url) throws Exception {
		
		Document documnet = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(url); // 获得document对象
		Element root = documnet.getDocumentElement();
		System.out.println("<?xml version = \"1.0\" encoding = \"utf-8\"?>");
		walkNode(root);
	}

	/**
	 * 遍历元素节点
	 * @param element
	 */
	public static void walkNode(Element element){
		
		String nodeName = element.getNodeName();
		System.out.print("<" + nodeName);
		parseAttr(element);
		System.out.print(">");
		
		NodeList nodeList = element.getChildNodes();
		if (nodeList!=null&&nodeList.getLength()>0) {
			for (int i = 0; i < nodeList.getLength(); i++) {
				Node node = nodeList.item(i);
				if (node.getNodeType() == Node.ELEMENT_NODE) {
					walkNode((Element) node); 													// 递归
				} else if (node.getNodeType() == Node.TEXT_NODE) {
					System.out.print(node.getNodeValue());
				} else if (node.getNodeType() == Node.COMMENT_NODE) {
					System.out.print("<!-- " + node.getNodeValue() + " -->");
				} else if (node.getNodeType() == Node.CDATA_SECTION_NODE) {
					System.out.print("<![CDATA[" + node.getNodeValue() + "]]>");
				}
			}
		}
		
		System.out.print("</" + nodeName + ">");
	}

	/**
	 * 遍历属性节点
	 * @param element
	 */
	public static void parseAttr(Element element) {

		NamedNodeMap attrs = element.getAttributes();
		if (attrs != null && attrs.getLength() > 0) {
			System.out.print(" ");
			for (int i = 0; i < attrs.getLength(); i++) {
				System.out.print(attrs.item(i).getNodeName() + " = \"" + attrs.item(i).getNodeValue() + "\" ");
			}
		}
	}
	
	
	
}
